﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using ZedGraph;
using System.IO;

namespace WindowsFormsApplication3 {
    public partial class Graph : UserControl {

        #region Fields

        private PointPairList _amperageList;
        private PointPairList _voltageList;
        private PointPairList _speedList;
        private PointPairList _distanceList;
        private PointPairList _wattageList;
        private PointPairList _temperatureList;
        private GraphPane _myPane;

        private int _dataCount;

        #endregion

        /// <summary>
        /// Constructor
        /// </summary>
        public Graph()
        {
            InitializeComponent();
            zedGraphControl.PointValueEvent += zedGraphControl_PointValueEvent;
        }

        /// <summary>
        /// Create the graph
        /// </summary>
        private void createGraph()
        {
            // get a reference to the GraphPane
            _myPane = zedGraphControl.GraphPane;
            _myPane.Chart.Fill.Brush = new SolidBrush(Color.Black);

            //Set main graph details
            _myPane.Title.Text = "Car information";
            _myPane.XAxis.Title.Text = "Packet number";
            _myPane.YAxis.Title.Text = "Value";

            //Create lists
            _amperageList = new PointPairList();
            _voltageList = new PointPairList();
            _speedList = new PointPairList();
            _distanceList = new PointPairList();
            _wattageList = new PointPairList();
            _temperatureList = new PointPairList();

            //Create curves
            LineItem myAmperageCurve = _myPane.AddCurve("Amperage", _amperageList, Color.Red, SymbolType.None);
            myAmperageCurve.Line.Width = 2.0f;
            LineItem myVoltageCurve = _myPane.AddCurve("Voltage", _voltageList, Color.Blue, SymbolType.None);
            myVoltageCurve.Line.Width = 2.0f;
            LineItem mySpeedCurve = _myPane.AddCurve("Speed", _speedList, Color.LightGreen, SymbolType.None);
            mySpeedCurve.Line.Width = 2.0f;
            LineItem myDistanceCurve = _myPane.AddCurve("Distance", _distanceList, Color.Pink, SymbolType.None);
            myDistanceCurve.Line.Width = 2.0f;
            LineItem myWattageCurve = _myPane.AddCurve("Wattage", _wattageList, Color.Yellow, SymbolType.None);
            myWattageCurve.Line.Width = 2.0f;
            LineItem myTemperatureCurve = _myPane.AddCurve("Temperature", _temperatureList, Color.White, SymbolType.None);
            myTemperatureCurve.Line.Width = 2.0f;
        }

        /// <summary>
        /// Update graph afer receiving a new value
        /// </summary>
        /// <param name="dataCount"></param>
        /// <param name="amperage"></param>
        /// <param name="voltage"></param>
        /// <param name="speed"></param>
        /// <param name="wattage"></param>
        public void updateGraph(double amperage, double distance, double speed, double voltage, double wattage, double temperature)
        {
            _dataCount++;
            _amperageList.Add(_dataCount, amperage);
            _voltageList.Add(_dataCount, voltage);
            _speedList.Add(_dataCount, speed);
            _distanceList.Add(_dataCount, distance);
            _wattageList.Add(_dataCount, wattage);
            _temperatureList.Add(_dataCount, temperature);

            // Tell ZedGraph to refigure the
            // axes since the data have changed
            zedGraphControl.AxisChange();
            zedGraphControl.Invalidate();
        }

        /// <summary>
        /// Set the dimensions of the graph
        /// </summary>
        public void SetSize()
        {
            zedGraphControl.Location = new Point(10, 10);

            // Leave a small margin around the outside of the control
            zedGraphControl.Size = new Size(ClientRectangle.Width - 20, ClientRectangle.Height - 20);
        }

        /// <summary>
        /// Change the visibility of the lines
        /// </summary>
        /// <param name="lineName">Name of the line</param>
        /// <param name="visible">Visibility true or false</param>
        public void LineVisibility(string lineName, bool visible)
        {
            foreach (var line in _myPane.CurveList)
            {
                if (line.Label.Text.ToString() == lineName)
                {
                    line.IsVisible = visible;
                    zedGraphControl.AxisChange();
                    zedGraphControl.Invalidate();
                }
            }
        }

        #region Events

        /// <summary>
        /// [EVENT] Create graph and set size once all the components of the usercontrol are loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Graph_Load(object sender, EventArgs e)
        {
            createGraph();
            SetSize();
        }

        /// <summary>
        /// [EVENT] Change graph size too when resizing the usercontrol
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Graph_Resize(object sender, EventArgs e)
        {
            SetSize();
        }

        /// <summary>
        /// [EVENT] Get the value of the selected point
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="pane">Drawing area</param>
        /// <param name="curve">Selected curve</param>
        /// <param name="iPt">Selected point</param>
        /// <returns></returns>
        private string zedGraphControl_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt)
        {
            return curve.Label.Text + ": " + curve.Points[iPt].Y.ToString();
        }

        #endregion
    }
}